package com.wanho.java156.shiro.realm;

import com.wanho.java156.po.Permission;
import com.wanho.java156.po.Role;
import com.wanho.java156.po.User;
import com.wanho.java156.service.UserService;
import com.wanho.java156.util.MD5Util;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author zhang
 * @version 1.0
 * @date 2021/4/11
 */
public class CustomDBRealm extends AuthorizingRealm {
    @Autowired
    private UserService userService ;
    @Autowired
    private MD5Util md5Util ;

    /**
     * 认证信息
     * @param authenticationToken
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
        String username = token.getUsername();
        String password = new String(token.getPassword());
        //查询 用户主体信息  【单表查询】
        User user = userService.findByUsername(username);
        if (user==null){
            throw new UnknownAccountException("用户名不存在！") ;
        }
        //获得加密后的密码
        password = md5Util.md5(password,user.getSalt()) ;
        if (!user.getPassword().equals(password)){
            throw new IncorrectCredentialsException("密码错误!") ;
        }
        if (user.getStatus().equals(0)){
            throw new RuntimeException("用户账号冻结！") ;
        }
        //盐值
        ByteSource credentialsSalt = ByteSource.Util.bytes(user.getSalt());
        AuthenticationInfo info = new SimpleAuthenticationInfo(user, password,credentialsSalt, "customDBRealm");
        return info;
    }
    /*@Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
        String username = token.getUsername();
        String password = new String(token.getPassword());
        //查询 用户主体信息  【单表查询】
        User user = userService.findByUsername(username);
        if (user==null){
            throw new UnknownAccountException("用户名不存在！") ;
        }
        if (!user.getPassword().equals(password)){
            throw new IncorrectCredentialsException("密码错误!") ;
        }
        if (user.getStatus().equals(0)){
            throw new RuntimeException("用户账号冻结！") ;
        }
        AuthenticationInfo info = new SimpleAuthenticationInfo(user, password, "customDBRealm");
        return info;
    }*/

    /**
     * 授权
     * @param principalCollection
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        //获得 认证通过后的主体对象 user
        User currUser = (User) principalCollection.getPrimaryPrincipal();
        //根据 user的id 查询 user对应的角色及权限
        User user = userService.findById(currUser.getId());
        //获得对应的角色 及 权限
        List<Role> roleList = user.getRoles();
        //获得角色名 set 集合
        Set<String> roleNameSet = roleList.stream().map(Role::getRolename).collect(Collectors.toSet());
        Set<String> permNameSet = new HashSet<>() ;
        roleList.stream().forEach(role -> {
            permNameSet.addAll(role.getPermissions().stream().map(Permission::getPermissionname).collect(Collectors.toSet())) ;
        });

        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        info.addRoles(roleNameSet);
        info.addStringPermissions(permNameSet);
        return info;
    }
}
